/*
 *
 * Copyright (C) 1997 Jayakrishnan Nair jk@csr.uvic.ca
 * WWW: http://www.csc.uvic.ca/~jk
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
 * without fee is hereby granted, provided that any use properly
 * credits the author, i.e. "SlideProjector courtesy of <A
 * HREF="http://www.csc.UVic.CA/~jk"> Jayakrishnan Nair</A> is
 * displayed.
 *
 * ChangeLog
 * July 20, 1998
 *  
 */
import java.applet.Applet;
import java.awt.*;
import java.util.*;
import java.net.*;
import java.io.*;

public class SlideProjector extends Applet implements Runnable {

  public static final int NEXT_IMAGE = 1001;
  public static final int PREV_IMAGE = 1002;
  public static final int RANDOM_TRANSITION = 1003;
  public static final int NORMAL_TRANSITION = 1004;
  
  ToolBar tb;
  SilverScreen ss;
  Label label;
  int width;
  int height;
  
  Image[] images;
  Vector imageNames;
  Vector imageDisplayTitle;
  int numImages;
  int curImage;
  String fontName;
  String fontSize;
  int transitionType;
  String copyRight;
  String separator;

  MediaTracker tracker;
  Thread ssThread;
  Font f;
  int delay;

  public void init() {

    curImage = -1;
    imageNames = new Vector();
    imageDisplayTitle = new Vector();


    String paramString = getParameter("WIDTH");
    if(paramString != null) {
      width = Integer.valueOf(paramString).intValue();
    }

    paramString = getParameter("HEIGHT");
    if(paramString != null) {
      height = Integer.valueOf(paramString).intValue();
    }

    copyRight = getParameter("URL");

    separator = getParameter("SEPARATOR");
    if(separator == null)
      separator = "|";

    paramString = getParameter("TRANSITION");
    if (paramString == null)
      paramString = "RANDOM";

    if (paramString == "RANDOM")
      transitionType = RANDOM_TRANSITION;
    else
      transitionType = NORMAL_TRANSITION;
    
    paramString = getParameter("TRANSITIONDELAY");
    if (paramString != null) {
      delay = Integer.valueOf(paramString).intValue();
    } else {
      delay = 10000;
    }
	

    int fh = Integer.parseInt(getParameter("FONTHEIGHT"));
    int i = fh;
    while (i > 10) {
      f = new Font(getParameter("font"), Font.PLAIN, i);
      FontMetrics fm = getFontMetrics(f);
      if (fm.getHeight() <= fh) {
	break;
      }
      i--;
    } 

    // Find out how many images are there
    try {
      String tempString;
      int point;
      i = 0;
      while ((paramString = getParameter("SLIDE"+i)) != null) {
	point = paramString.indexOf(separator);
	tempString = paramString.substring(0,point);
	System.out.println("Image Name = "+tempString+" "+ i);
	this.showStatus("Image Name = "+tempString+" i");
	imageNames.addElement(tempString);
	tempString = paramString.substring(point+1);
	imageDisplayTitle.addElement(tempString);
	this.showStatus("Display Name = "+tempString);
	i++;
      }
	  
    } catch(Exception e) {
      this.showStatus("SlideProjector: Error in SLIDE PARAMETER");
    }
    numImages = imageNames.size();

    tracker = new MediaTracker(this);
    images = new Image[numImages];

    String fa = getParameter("RIGHTARROWIMAGE");
    if ( fa == null)
      fa = "forward.gif";

    String fb = getParameter("LEFTARROWIMAGE");
    if(fb == null)
      fb = "backward.gif";
 
    String fi = getParameter("TITLEIMAGE");
    if(fi == null)
      fi = "title.gif";

    tb = new ToolBar(this,width,fa,fb,fi,50);
    ss = new SilverScreen(width,height-90,this);
    label = new Label("Click on right arrow to see next slide",Label.CENTER);

    label.setFont(f);

    Border b = new Border(tb,2);
    b.setLineColor(Color.black);

    Border screenBorder = new Border(ss,2);
    screenBorder.setLineColor(Color.black);

    Border labelBorder = new Border(label,2);
    labelBorder.setLineColor(Color.black);

    Panel p = new Panel();

    p.setLayout(new BorderLayout(0,0));
    p.add("North",screenBorder);
    p.add("Center",labelBorder);
    p.add("South",b);

    add(p);
  }


  public void start() {
    if(ssThread == null) {
      ssThread = new Thread(this);
      ssThread.start();
    }
  }


  public void stop() {
    if((ssThread != null)&&ssThread.isAlive())
      ssThread.stop();
    ssThread = null;
  }


  public void run() {
    ssThread.setPriority(Thread.MAX_PRIORITY);
    for(int i = 0; i < numImages; i++) {
      String myName = (String)imageNames.elementAt(i);
      new ImageLoader(this,i,myName);
    }
  }
  
  public void showNextImage() {
    curImage = curImage + 1;
    if (curImage > images.length-1) curImage = 0;
    //            curImage = ++curImage % images.length;
    //            curImage = (curImage < 0) ? -curImage :curImage;
    showMessage("Next: "+curImage);
    //    ss.clearDisplay();
    ss.displayImage(images[curImage]);
    label.setText((String)imageDisplayTitle.elementAt(curImage));
  }

  public void showPrevImage() {
    curImage = curImage - 1;
    if (curImage < 0) curImage = images.length-1;
    //            curImage = (curImage-1) % images.length;
    //            curImage = (curImage < 0) ? -curImage : curImage;

    showMessage("Prev: "+curImage+"images.length="+images.length);
    if(!tracker.checkID(curImage,true)) {
      try {
	tracker.waitForID(0);
      } catch(Exception e) {
	this.showStatus("Error waiting for Image "+curImage);
      }
    }
    //    ss.clearDisplay();
    ss.displayImage(images[curImage]);
    label.setText((String)imageDisplayTitle.elementAt(curImage));
  }




  public boolean handleEvent(Event e) {
    if(e.id == SlideProjector.NEXT_IMAGE) {

      showNextImage();
      return true;
    }
    if(e.id == SlideProjector.PREV_IMAGE) {
      showPrevImage();
      return true;
    }
    return false;
  }


  public void showMessage(String s) {
    this.showStatus(s);
  }

  public void paint(Graphics g) {

  }

  public String getAppletInfo()    {
    return "SlideProjector Applet by Jayakrishnan Nair jk@csr.UVic.CA http://csr.csc.UVic.CA/~jk";
  }

  public String[][] getParameterInfo() {
    String[][] info = {
      {"WIDTH", "int", "the width of the applet"},
      {"HEIGHT", "int", "the height of the applet"},
      {"FONT", "String", "a valid Java Font name"},
      {"FONTHEIGHT", "int", "size of the font"},
      {"LEFTARROWIMAGE","String", "URL of the left arrow in the toolbutton"},
      {"RIGHTARROWIMAGE","String", "URL of the right arrow in the toolbutton"},
      {"TITLEIMAGE","String","URL of the title image - one which says SlideProjector"},
      {"SEPARATOR","String","Separator used the SLIDE parameter"},
      {"SLIDE1..N","String", "URL of image <separator> title of image"},
    };
    return info;
  }

  int getProjectorWidth() {
    return width;
  }

  int getProjectorHeight() {
    return height;
  }

  int getTransitionType() {
    return transitionType;
  }

  int getDelay() {
    return delay;
  }

}


